package whut.GA;

import org.apache.commons.math3.genetics.AbstractListChromosome;
import org.apache.commons.math3.genetics.BinaryChromosome;
import org.apache.commons.math3.genetics.InvalidRepresentationException;
import whut.commons.IProblemSet;
import whut.commons.Location;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Justin on 2018-04-20
 */
public class BinaryArray extends BinaryChromosome {
    private static IProblemSet problem;
    private static IBinaryEncoder encoder;

    public BinaryArray(Integer[] representation) throws InvalidRepresentationException {
        super(representation);
    }

    public BinaryArray(List<Integer> representation) throws InvalidRepresentationException {
        super(representation);
    }

    public static void setProblem(IProblemSet problem) {
        BinaryArray.problem = problem;
    }

    public static void setEncoder(IBinaryEncoder encoder) {
        BinaryArray.encoder = encoder;
    }

    @Override
    public AbstractListChromosome<Integer> newFixedLengthChromosome(List<Integer> chromosomeRepresentation) {
        return new BinaryArray(chromosomeRepresentation);
    }

    @Override
    public double fitness() {
        double num;
        List<Integer> list = this.getRepresentation();
        double[] XY = encoder.decoding(list);
        Location location = new Location(XY);
        num = problem.evaluate(location);
        return 0 - num;
    }

    public static AbstractListChromosome createBinaryChromosome(Location loc){
        List<Integer> result = encoder.coding(loc.getLoc());
        return new BinaryArray(result);
    }

    @Override
    public String toString(){
        List<Double> list = new ArrayList<>();
        double[] location = encoder.decoding(this.getRepresentation());
        if(location == null){
            return "error";
        }
        if(location.length !=0) {
            list.add(location[0]);
            list.add(location[1]);
        }
        return String.format("f = %.6E %s", -this.getFitness(),list);
    }
}
